package org.jeecg.modules.charge.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.model.charge.reqvo.DayReportReqVo;
import org.jeecg.model.charge.resvo.DayReportRespVo;
import org.jeecg.modules.charge.service.IChargeBillsOrderService;
import org.jeecg.service.IFeignCarService;
import org.jeecg.service.IFeignMeterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sound.midi.Soundbank;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Mr shaopeng
 * @date 2021/3/2 18:11
 */
@Api(tags = "日收款汇总报表")
@Slf4j
@RestController
@RequestMapping("/b/charge/dayReport")
public class DayReportController {

    @Autowired
    private IChargeBillsOrderService chargeBillsOrderService;
    @Autowired
    private IFeignMeterService feignMeterService;
    @Autowired
    private IFeignCarService feignCarService;


    @AutoLog(value = "日收款汇总报表-列表查询")
    @ApiOperation(value = "日收款汇总报表-列表查询", notes = "日收款汇总报表-列表查询")
    @GetMapping(value = "/list")
    public Result<List<DayReportRespVo>> queryPageList(DayReportReqVo dayReportReqVo) {
        log.info("日收款汇总报表-列表查询接受参数:{}",dayReportReqVo);
        try {
            DayReportRespVo totalVo = new DayReportRespVo("合计","-","-");//合计
            if (StringUtils.isBlank(dayReportReqVo.getProjectId()) || StringUtils.isBlank(dayReportReqVo.getProjectName())){
                return Result.error("查询数据有误！");
            }
            if (dayReportReqVo.getSearchStartTime() == null){
                dayReportReqVo.setSearchStartTime(DateUtils.getDateStart(new Date()));
            }
            if (dayReportReqVo.getSearchEndTime() == null || dayReportReqVo.getSearchEndTime().compareTo(new Date()) > 0){
                dayReportReqVo.setSearchEndTime(new Date());
            }
            LoginUser user = SsoUtil.getLoginUser();
            List<DayReportRespVo> totalOrderList = new ArrayList<>();

            //收费模块
            Map<String,DayReportRespVo> chargeOrderMap = new LinkedHashMap<>();
            Map<String,DayReportRespVo> meterOrderMap = new LinkedHashMap<>();
            Map<String,DayReportRespVo> carOrderMap = new LinkedHashMap<>();
            if (StringUtils.isBlank(dayReportReqVo.getReportClass()) || dayReportReqVo.getReportClass().equals("charge")){
                List<DayReportRespVo> chargeOrderList = chargeBillsOrderService.findGroupList(dayReportReqVo);
                if (chargeOrderList.size() > 0){
                    chargeOrderMap = chargeOrderList.stream().collect(Collectors.toMap(DayReportRespVo::getCoverDate, Function.identity()));
                }
            }
            //能耗模块
            if (StringUtils.isBlank(dayReportReqVo.getReportClass()) || dayReportReqVo.getReportClass().equals("meter")){
                List<DayReportRespVo> meterOrderList = feignMeterService.meterFindGroupList(dayReportReqVo, user.getTenantId());
                if (meterOrderList.size() > 0){
                    meterOrderMap = meterOrderList.stream().collect(Collectors.toMap(DayReportRespVo::getCoverDate, Function.identity()));
                }
            }
            //车辆月卡
            if (StringUtils.isBlank(dayReportReqVo.getReportClass()) || dayReportReqVo.getReportClass().equals("carOrder")){
                List<DayReportRespVo> carOrderList = feignCarService.carFindGroupList(dayReportReqVo, user.getTenantId());
                if (carOrderList.size() > 0){
                    carOrderMap = carOrderList.stream().collect(Collectors.toMap(DayReportRespVo::getCoverDate, Function.identity()));
                }
            }
            Set<String> allSetDate = new LinkedHashSet<>();
            // 目的:查询出来的结果可能某个日期没有数据,需要和整个查询日期期间比较将没有的日期找出来,设置一个空对象进去
            while (dayReportReqVo.getSearchEndTime().compareTo(dayReportReqVo.getSearchStartTime()) >= 0 ){
                allSetDate.add(DateUtils.date2Str(dayReportReqVo.getSearchStartTime(),DateUtils.date_sdf));
                dayReportReqVo.setSearchStartTime(DateUtils.addDate(dayReportReqVo.getSearchStartTime(),1));
            }
            Iterator<String> it = allSetDate.iterator();
            while (it.hasNext()) {
                String tempDate = it.next();
                DayReportRespVo chargeVo = chargeOrderMap.get(tempDate);
                if (chargeVo == null) {
                    chargeVo = new DayReportRespVo(dayReportReqVo.getProjectName(),"收费模块",tempDate);
                } else {
                    chargeVo.setProjectName(dayReportReqVo.getProjectName());
                }
                totalOrderList.add(chargeVo);
                DayReportRespVo meterVo = meterOrderMap.get(tempDate);
                if (meterVo == null) {
                    meterVo = new DayReportRespVo(dayReportReqVo.getProjectName(),"能耗模块",tempDate);
                } else {
                    meterVo.setProjectName(dayReportReqVo.getProjectName());
                }
                totalOrderList.add(meterVo);
                DayReportRespVo carVo = carOrderMap.get(tempDate);
                if (carVo == null) {
                    carVo = new DayReportRespVo(dayReportReqVo.getProjectName(),"停车模块",tempDate);
                } else {
                    carVo.setProjectName(dayReportReqVo.getProjectName());
                }
                totalOrderList.add(carVo);
            }
            //todo  商户缴费
            calculateTotal(totalVo, totalOrderList); //计算合计\
            ListSort(totalOrderList);//重新按时间排列顺序
            totalOrderList.add(totalVo);
            return Result.ok(totalOrderList);
        }catch (Exception e){
            log.error(e.getMessage(), e);
            return Result.error("获取报表信息出错！");
        }
    }

    /**
     * 计算合计
     * @param totalVo
     * @param subVo
     */
    private void calculateTotal(DayReportRespVo totalVo, List<DayReportRespVo> subVo) {
        for (DayReportRespVo sub : subVo){
            totalVo.setFFT(totalVo.getFFT().add(sub.getFFT()));
            totalVo.setCEB(totalVo.getCEB().add(sub.getCEB()));
//            totalVo.setNP(totalVo.getNP().add(sub.getNP()));
            totalVo.setXianJin(totalVo.getXianJin().add(sub.getXianJin()));
            totalVo.setZhuanZhang(totalVo.getZhuanZhang().add(sub.getZhuanZhang()));
            totalVo.setAlipay(totalVo.getAlipay().add(sub.getAlipay()));
            totalVo.setWeixinpay(totalVo.getWeixinpay().add(sub.getWeixinpay()));
            totalVo.setWechatapplet(totalVo.getWechatapplet().add(sub.getWechatapplet()));
            totalVo.setPos(totalVo.getPos().add(sub.getPos()));
//            totalVo.setScanOffline(totalVo.getScanOffline().add(sub.getScanOffline()));
            totalVo.setSubTotal(totalVo.getSubTotal().add(sub.getSubTotal()));
            totalVo.setWechat(totalVo.getWechat().add(sub.getWechat()));
            totalVo.setOffline(totalVo.getOffline().add(sub.getOffline()));
            totalVo.setAppScanner(totalVo.getAppScanner().add(sub.getAppScanner()));
            totalVo.setApp(totalVo.getApp().add(sub.getApp()));
            totalVo.setScanner(totalVo.getScanner().add(sub.getScanner()));
        }
    }

    private void ListSort(List<DayReportRespVo> list) {
        {    //排序方法
            Collections.sort(list, new Comparator<DayReportRespVo>() {
                @Override
                public int compare(DayReportRespVo o1, DayReportRespVo o2) {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date dt1 = format.parse(o1.getCoverDate());
                        Date dt2 = format.parse(o2.getCoverDate());
                        // 这是由大向小排序   如果要由小向大转换比较符号就可以
                        if (dt1.getTime() < dt2.getTime()) {
                            return -1;
                        } else if (dt1.getTime() > dt2.getTime()) {
                            return 1;
                        } else {
                            return 0;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return 0;
                }
            });
        }
    }
}
